﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Unity;
using SportTraining.Helpers;
using SportTraining.Core.Dal;
using SportTraining.Core.Domain;
using SportTraining.Core.Services;

namespace SportTraining.MVVM.Model.Impl
{
    public class PaymentProcedureModel : BaseModel, IPaymentProcedureModel
    {
        #region private field

        private PaymentTransaction paymentTransaction;

        #endregion

        #region dependency property

        public PaymentProcedureModel()
        {
            paymentTransaction = new PaymentTransaction();
        }

        [Dependency]
        public IDataContext DataContext { get; set; }

        [Dependency]
        public ISectionDal SectionDal { get; set; }

        [Dependency]
        public IPaymentDal PaymentDal { get; set; }

        [Dependency]
        public IBillAcceptor BillAcceptor { get; set; }

        [Dependency]
        public IFiscalRegister FiscalRegister { get; set; }

        #endregion

        #region Implementation of IPaymentProcedureModel

        public void SavePayment(IPayment payment)
        {
            try
            {
                // сохрание в БД
                paymentTransaction.State = TransactionState.SaveToDb;

                PaymentDal.Add(payment);
                DataContext.Save();

                // печать чека
                paymentTransaction.State = TransactionState.PrintCheck;

                FiscalRegister.PrintCheck(CheckHelper.GetCheck(payment));

                paymentTransaction.State = TransactionState.Completed;
            }
            finally
            {
                paymentTransaction.Clear();
                paymentTransaction = null;
            }
        }


        public IList<ISection> GetEnableSections()
        {
            return SectionDal.SelectAll().ToList();
        }

        public void PrintPayment(IPayment payment)
        {
            FiscalRegister.PrintCheck(CheckHelper.GetCheck(payment));
        }

        public IPayment CreatePayment(ISection section)
        {
            var payment = PaymentDal.CreatePayment(section);
            paymentTransaction.Payment  = payment;
            return payment;
        }

        public void StartWaitMoney()
        {
            BillAcceptor.ReceiveMoneyEvent += BillAcceptorReceiveMoneyEvent;
            BillAcceptor.ErrorEvent += BillAcceptorErrorEvent;

            BillAcceptor.StartWaitMoney();
        }

        public void StopWaitMoney()
        {
            BillAcceptor.StopWaitMoney();

            BillAcceptor.ReceiveMoneyEvent -= BillAcceptorReceiveMoneyEvent;
            BillAcceptor.ErrorEvent -= BillAcceptorErrorEvent;
        }

        public event EventHandler<BillAcceptorEventArgs> ReceiveMoneyEvent;
        public event EventHandler<TerminalDeviceErrorEventArgs> ErrorEvent;

        #endregion

        #region events

        private void BillAcceptorErrorEvent(object sender, TerminalDeviceErrorEventArgs e)
        {
            paymentTransaction.State = TransactionState.ReceiveMoney;

            if (ErrorEvent != null)
            {
                ErrorEvent(this, e);
            }
        }

        private void BillAcceptorReceiveMoneyEvent(object sender, BillAcceptorEventArgs e)
        {
            paymentTransaction.State = TransactionState.ReceiveMoney;

            if (ReceiveMoneyEvent != null)
            {
                ReceiveMoneyEvent(this, e);
            }
        }
        #endregion
    }
}